using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Matrix.Configuration.Events;

namespace Matrix.Configuration.Services
{
    /// <summary>
    /// 配置热更新服务接口
    /// 支持IOptionsMonitor模式的动态配置更新
    /// </summary>
    public interface IConfigurationWatcher : IDisposable
    {
        /// <summary>
        /// 配置变更事件
        /// </summary>
        event EventHandler<ConfigurationChangedEventArgs> ConfigurationChanged;

        /// <summary>
        /// 启动配置监听
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>监听任务</returns>
        Task StartWatchingAsync(CancellationToken cancellationToken = default);

        /// <summary>
        /// 停止配置监听
        /// </summary>
        Task StopWatchingAsync();

        /// <summary>
        /// 检查是否正在监听
        /// </summary>
        bool IsWatching { get; }

        /// <summary>
        /// 获取监听的配置键列表
        /// </summary>
        IReadOnlyList<string> WatchedKeys { get; }

        /// <summary>
        /// 统计信息
        /// </summary>
        ConfigurationSubscriptionStatistics Statistics { get; }

        /// <summary>
        /// 添加监听的配置键
        /// </summary>
        /// <param name="key">配置键</param>
        /// <param name="namespace">命名空间</param>
        void AddWatchKey(string key, string? @namespace = null);

        /// <summary>
        /// 移除监听的配置键
        /// </summary>
        /// <param name="key">配置键</param>
        /// <param name="namespace">命名空间</param>
        void RemoveWatchKey(string key, string? @namespace = null);

        /// <summary>
        /// 手动触发配置变更检查
        /// </summary>
        /// <returns>是否有配置变更</returns>
        Task<bool> TriggerCheckAsync();

        /// <summary>
        /// 订阅配置变更
        /// </summary>
        /// <param name="key">配置键</param>
        /// <param name="namespace">命名空间</param>
        /// <param name="callback">回调函数</param>
        /// <returns>订阅句柄</returns>
        IDisposable SubscribeOnChange(string key, string? @namespace, Action<ConfigurationChangedEventArgs> callback);

        /// <summary>
        /// 订阅类型化配置变更
        /// </summary>
        /// <param name="key">配置键</param>
        /// <param name="namespace">命名空间</param>
        /// <param name="callback">回调函数</param>
        /// <returns>订阅句柄</returns>
        IDisposable SubscribeOnChange<T>(string key, string? @namespace, Action<ConfigurationChangedEventArgs<T>> callback);

        /// <summary>
        /// 获取当前配置值
        /// </summary>
        /// <typeparam name="T">配置类型</typeparam>
        /// <param name="key">配置键</param>
        /// <param name="namespace">命名空间</param>
        /// <returns>配置值</returns>
        Task<T?> GetCurrentAsync<T>(string key, string? @namespace = null);

        /// <summary>
        /// 清除所有订阅
        /// </summary>
        void ClearAllSubscriptions();

        /// <summary>
        /// 获取统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        ConfigurationSubscriptionStatistics GetStatistics();
    }

    }